package com.CMS.server.dao;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;

import com.CMS.server.Idomain.IBaseDao;

/*Esta clase represnta el Dao base, del cual van a extender las especializaciones*/


public class BaseDao<T> implements IBaseDao<T>{
	
	@SuppressWarnings("unchecked")
	protected Class<T> domainClass = getDomainClass();
	
	protected static final EntityManager entityManager() {
		return Emf.get().createEntityManager();
	}
	
	@Override
	public void createEntity(T entity)
	{
		EntityManager em = Emf.get().createEntityManager();
		EntityTransaction tx = em.getTransaction();
		try
		{
			tx.begin();
			em.persist(entity);
			tx.commit();
		}
		catch(Exception e){
			tx.rollback();
			e.printStackTrace();
		}
		finally{
			em.close();
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public T getEntity(long id) {
		EntityManager em = entityManager();
		T ent = null;		
		String clase = domainClass.getName().substring(22);
		try{
			Query q = em.createQuery("select e from "+clase+" e where e.id = ?1 and e.flagDelete = 0");
			q.setParameter(1, id);
			ent = (T)q.getSingleResult();
		}finally{ em.close();}
		
		return ent;
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	protected Class getDomainClass() {
	 	if (domainClass == null) {
			ParameterizedType thisType = (ParameterizedType) getClass().getGenericSuperclass();
			domainClass = (Class) thisType.getActualTypeArguments()[0];
	 	}
		return domainClass;
	}

	@Override
	public T updateEntity(T entity) {
		EntityManager em = entityManager();
		EntityTransaction tx = em.getTransaction();
		T ent = null;		
		try{
			tx.begin();
			ent = em.merge(entity);
			tx.commit();
		}
		catch (Exception e) {
			e.printStackTrace();
			tx.rollback();
		}
		finally{
			em.close();
		}
		
		return ent;
	}

	@Override
	public void deleteEntity(T entity) {
		EntityManager em = entityManager();
		EntityTransaction tx = em.getTransaction();
		T ent = null;
		//((BaseEntity)entity).setFlagDelete(true);
		try{
			tx.begin();
			ent = em.merge(entity);
			em.remove(ent);
			tx.commit();
		}
		catch (Exception e) {
			tx.rollback();
			e.printStackTrace();
		}
		finally{
			em.close();
		}		
	}
	
	@SuppressWarnings("unchecked")
	public List<T> getAll(){
		EntityManager em = entityManager();
		List<T> lista = null;
		String clase = domainClass.getName().substring(22);
		try
		{
			Query q = em.createQuery("select p from "+clase+" p where p.flagDelete = 0");
			lista = q.getResultList();
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		finally{
			em.close();
		}
		
		return lista;
	}
	
	@SuppressWarnings("unchecked")
	public T getEntityByDescription(String desc){
		EntityManager em = entityManager();
		T ent = null;		
		String clase = domainClass.getName().substring(22);
		try{
			Query q = em.createQuery("select e from "+clase+" e where e.description = ?1 and e.flagDelete = 0");
			q.setParameter(1, desc);
			ent = (T)q.getSingleResult();
		}finally{ em.close();}
		
		return ent;
	}

}
